package com.haiheng.voiceandbook.viewmodel

import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.haiheng.voiceandbook.BookRepository.BookRepository
import com.haiheng.voiceandbook.Constants
import com.haiheng.voiceandbook.Constants.Companion.BOOK_PATH
import com.haiheng.voiceandbook.MyApplication
import com.haiheng.voiceandbook.common.*
import com.haiheng.voiceandbook.utils.SpUtil
import com.ximalaya.ting.android.opensdk.model.category.Category
import com.ximalaya.ting.android.opensdk.model.category.CategoryList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import java.io.BufferedInputStream
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream

/**
 *
 */
class BookViewModel : ViewModel() {
    private val TAG = "BookViewModel"
    val repository = BookRepository()

    //    var categories: MutableLiveData<BaseDto<CategoriesDataDto>> = MutableLiveData()
    var categories: MutableLiveData<List<CategoriesDto>> = MutableLiveData()
    var books: MutableLiveData<BaseDto<BookMainDto>> = MutableLiveData()
    var bookDetail: MutableLiveData<BaseDto<BookDetailDataDto>> = MutableLiveData()
    var searchBooks: MutableLiveData<BaseDto<BookMainDto>> = MutableLiveData()
    var lastBook: MutableLiveData<AmountDataDto> = MutableLiveData()
    var hotBook: MutableLiveData<AmountDataDto> = MutableLiveData()
    var libraryName: MutableLiveData<String> = MutableLiveData()
    val page = 1
    val rows = 20

    /**
     * 获取所有书籍的分类
     *
     */
    fun categories() {
        viewModelScope.launch {
            try {
//                val data = repository.categories()
//                data.success = true
//                categories.value = data
                val data = repository.categoryList()

                libraryName.postValue(data.data?.name)
                categories.postValue(data.data?.ebookCategoriesV2)
                data.data?.let {
                    SpUtil.putString(
                        MyApplication.getInstance().applicationContext,
                        Constants.SP_LIBRARY_NAME, it.name
                    )
                    SpUtil.putString(
                        MyApplication.getInstance().applicationContext,
                        Constants.SP_LIBRARY_LOGO, it.logo
                    )
                }
            } catch (e: Exception) {
                Log.e(TAG, "categories: ${e}")
//                var dto = BaseDto<CategoriesDataDto>(500, null, "获取所有分类异常：${e.message}", false)
                categories.value = null

            }
        }
    }

    /**
     * 根据后台接口返回过滤喜马拉雅有声分类目录
     */
    suspend fun filterXimaVoiceCategories(list: CategoryList?): CategoryList? {
        return viewModelScope.async {
            try {
                var newCategoriesList = mutableListOf<Category>()
                var ximaCategoryListAll = list?.categories
                val settingCategoryDto = repository.getSettingCategories()
                settingCategoryDto.data?.let {
                    SpUtil.putString(
                        MyApplication.getInstance().applicationContext,
                        Constants.SP_LIBRARY_NAME, it.name
                    )
                    SpUtil.putString(
                        MyApplication.getInstance().applicationContext,
                        Constants.SP_LIBRARY_LOGO, it.logo
                    )
                }
                if (settingCategoryDto?.data?.enable == 1) {
                    var netCategoryList: List<String>
                    netCategoryList = settingCategoryDto?.data?.categories!!
                    ximaCategoryListAll?.forEach {
                        for (name in netCategoryList!!) {
                            if (it.categoryName.equals(name)) {
                                Log.e("test", "需要保留的分类:" + name)
                                newCategoriesList.add(it)
                                break
                            }
                        }
                    }
                }
                if (newCategoriesList.size > 0) {
                    if (list != null) {
                        list.categories = newCategoriesList
                    }
                }
                list
            } catch (e: Exception) {
                Log.e(TAG, "categories: ${e}")
                list
            }
        }.await()
    }

    /**
     * 获取所有书籍的分类
     * 带返回值
     *
     */
/*    suspend fun categoriesReturnData(): List<CategoriesDto>? {
        return viewModelScope.async {
            try {
                repository.categoryList()
            } catch (e: Exception) {
                Log.e(TAG, "categories: ${e}")
                null
            }
        }.await()
    }*/


    /**
     * 根据图书分类获取数据列表
     */
    fun booksByCategoryId(categoryId: Long, page: Int, rows: Int) {
        viewModelScope.launch {
            try {
                val data = repository.booksByCategoryId(categoryId, page, rows)
                data.success = true
                books.value = data
            } catch (e: Exception) {
                var dto = BaseDto<BookMainDto>(500, null, "通过分类获取书籍信息异常：${e.message}", false)
                books.value = dto
            }
        }
    }

    /**
     * 根据图书分类获取数据列表
     */
    suspend fun booksByCategoryIdReturnData(
        categoryId: Long,
        page: Int,
        rows: Int
    ): List<BookDto>? {
        return viewModelScope.async {
            try {
                val data = repository.booksByCategoryId(categoryId, page, rows)
                data.data?.data?.books
            } catch (e: Exception) {
                null
            }
        }.await()
    }

    /**
     * 获取书籍详细信息
     */
    suspend fun getBookDetail(bookId: Long): BookDetailInfoDto? {
        return viewModelScope.async {
            try {
                repository.getBookDetail(bookId).data?.data
            } catch (e: Exception) {
                Log.e(TAG, "获取书籍详情: ${e.message}")
                null
            }
        }.await()

    }

    /**
     * 获取书籍详细信息
     */
    suspend fun search(vo: SearchVo): List<BookDto>? {
        return viewModelScope.async {
            try {
                val data = repository.search(vo).data?.data?.books
                data
            } catch (e: Exception) {
                null
            }
        }.await()

    }

    /**
     * 获取最新排行
     */
    fun latestRank(page: Int, rows: Int) {
        Log.e(TAG, "latestRank: 开始请求")
        viewModelScope.launch {
            try {
                lastBook.value = repository.latestRank(page, rows)
                Log.e(TAG, "latestRank: lastBook = ${lastBook.value}")
            } catch (e: Exception) {
                Log.e(TAG, "latestRank: " + e.message)
            }


        }
    }

    /**
     * 获取热门排行
     */
    fun hotRank(page: Int, rows: Int) {
        Log.e(TAG, "hotRank: 开始请求")
        viewModelScope.launch {
            try {
                hotBook.value = repository.hotRank(page, rows)
                Log.e(TAG, "hotRank: hotBook = ${hotBook.value}")
            } catch (e: Exception) {
                Log.e(TAG, "hotRank: " + e.message)
            }
        }
    }

    /**
     * 下载的文件
     */
    suspend fun downLoadUrl(path: String?, fileName: String?, bookType: String?): String? {
        return viewModelScope.async(Dispatchers.IO) {
            try {
//                var testUrl = "http://218.17.192.253:9000/zybook/112234002%E8%8D%AF%E8%86%B3%E4%B8%93%E5%AE%B6%E7%9A%841001%E5%85%BB%E7%94%9F%E4%BA%8B%E5%85%B8.epub?1634382494264";
                Log.e(TAG, "downLoadUrl: 开始请求下载....："+path)
//                val result = repository.downLoadUrl(testUrl)
                val result = repository.downLoadUrl(path)
                Log.e(TAG, "downLoadUrl: 文件大小" + result.contentLength())
                val fileDr = File(BOOK_PATH)
                if (!fileDr.exists()) {
                    fileDr.mkdir()
                }
                val file = File(BOOK_PATH, fileName)
                //文件存在
                if (file.exists()) {
                    //文件大小
                    val fileLength = file.length()
                    //判断是否要下载
                    val length = result.contentLength()
                    //文件不完整
                    if (fileLength < length) {
                        //删掉重来
                        file.delete()
                        //写文件
                        writeFile(file, result.byteStream())
                    }
                }
                //文件不存在
                else {
                    file.createNewFile()
                    writeFile(file, result.byteStream())
                }
                Log.e(TAG, "下载完毕${Thread.currentThread().name},${path}")
                fileName
            } catch (e: Exception) {
                Log.e(TAG, "下载完毕失败: " + e.message)
                "1"
            }
        }.await()
    }

    /**
     * 写入文件
     */
    fun writeFile(file: File, input: InputStream) {
        val fos = FileOutputStream(file)
        val bis = BufferedInputStream(input)
        val buffer = ByteArray(1024)
        var len: Int
        var total: Long = 0
        while ((bis.read(buffer).also { len = it } != -1)) {
            Log.e(TAG, "downLoadUrl: 正在写入文件${len}")
            fos.write(buffer, 0, len)
            total += len
        }
        Log.e(TAG, "当前: len = ${len}")
        fos.flush()
        fos.close()
        bis.close()
        input.close()

    }


    fun reportAlbumClick(albumId:String){
        viewModelScope.launch {
            try {
               var result =  repository.reportAlbumClick(albumId)
                Log.i(TAG, "上报专辑点击${result}")
            }catch (ex:Exception){
                Log.e(TAG, "reportAlbumClick Exception : ${ex}")
            }
        }
    }

    fun reportPlay(albumId:String,timer:Long){
        viewModelScope.launch {
            try {
                var result =  repository.reportPlay(albumId,timer)
                Log.i(TAG, "reportPlay ${result}")
            }catch (ex:Exception){
                Log.e(TAG, "reportPlay Exception : ${ex}")
            }
        }
    }

    fun reportReading(bookId:String,timer:Long){
        viewModelScope.launch {
            try {
                var result =  repository.reportReading(bookId,timer)
                Log.i(TAG, "reportReading ${result}")
            }catch (ex:Exception){
                Log.e(TAG, "reportReading Exception : ${ex}")
            }
        }
    }

    fun reportReadTimes(bookId:String?){
        viewModelScope.launch {
            try {
                var result = bookId?.let { repository.reportReadTimes(it) }
                Log.i(TAG, "reportReadTimes ${result}")
            }catch (ex:Exception){
                Log.e(TAG, "reportReadTimes Exception : ${ex}")
            }
        }
    }
}

